/*
 *  index.c
 *
 *  Harry Wei <harryxiyou@gmail.com> (C) 2013
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define KEY_FILE		"D:\\test\\KEGG_p-value.txt"
#define INDEX_FILE		"D:\\test\\index.txt"
#define NUM				(50U)
#define MEM				(1024U)
#define DEBUG
#undef DEBUG

#ifdef	__COMPILER
struct link {
	struct link *prev;
	struct link *next;
};
#endif

struct index {
	char num_str[NUM];
	char key_str[NUM];
	int offset;
	struct index *next;
};

struct key {
	char key_str[NUM];
	char *num_str[NUM];
	int length;
	struct key *next;
};

int free_jobs(struct index *head, struct key *_head) {
	/*TODO: Actual free jobs*/
	return 0;
}

int write2index(struct index *head) {
	FILE *fp = NULL;
	struct index *ihead = head->next;

	fp = fopen(INDEX_FILE, "wt");
	if (NULL == fp) {
		fprintf(stderr, "fopen file error!\n");
		return -1;
	}
	while (NULL != ihead) {
		fprintf(fp, "%s %s\n", ihead->num_str, ihead->key_str);
		ihead = ihead->next;
	}
	fclose(fp);
	return 0;
}

int map_keystr(struct index *head, struct key *_head) {
	struct index *ihead = head;
	struct key *khead = _head;
	int i = 0;
	int ret = 0;

	printf("999 enter func map_keystr\n");
	if (NULL == head || NULL == _head) {
		fprintf(stderr, "Parameter Error!\n");
		return -1;
	}
	ihead = ihead->next;
	khead = khead->next;
	while (NULL != ihead) {
		memset(ihead->key_str, '\0', NUM);
		ihead->offset = 0;
		while (NULL != khead) {
			for (i = 0; i < khead->length; i++) {
				if (0 == strcmp(khead->num_str[i], ihead->num_str)) {
					//sprintf(ihead->key_str, "%s", khead->key_str);
					//printf("%s\n", khead->key_str);
					sprintf(ihead->key_str + ihead->offset, " %s", khead->key_str);
					ihead->offset = strlen(khead->key_str);
				}
			}
			khead = khead->next;
		}
		khead = _head->next;
		ihead = ihead->next;
	}
#ifdef DEBUG
	ihead = head->next;
	while (NULL != ihead) {
		printf("%s %s\n", ihead->num_str, ihead->key_str);
		ihead = ihead->next;
	}
#endif
	ret = write2index(head);
	if (0 > ret) {
		fprintf(stderr, "write2index error!\n");
		return -1;
	}
	printf("999 leave func map_keystr\n");
	return 0;
}

/*
 * HOWTO
 * 1, Split index.txt buf with '\n' and put them into
 *    struct index DS.
 * 2, Split KEGGxx.txt buf first with '\n', then split
 *    smaller ones with '\t'.
 * 3, Compare struct index's num_str filed with 2's 
 *    results, then put found key_str into struct index's
 *    key_str field.
 * 4, Write all struct index into index file.
 */

int main(int argc, char *argv[]) {
	char text[MEM];
	char _text[MEM];
	FILE *fp = NULL;
	struct index *head = NULL;
	struct index *follow = NULL;
	struct index *allocate = NULL;
	FILE *_fp = NULL;
	struct key *_head = NULL;
	struct key *_follow = NULL;
	struct key *_allocate = NULL;
	int flag = 0;
	int i = 0;
	int ret = 0;

	memset(text, '\0', MEM);
	fp = fopen(INDEX_FILE, "rt");
	if (NULL == fp) {
		fprintf(stderr, "fopen file %s error!\n", INDEX_FILE);
		return -1;
	}
	allocate = (struct index *) malloc(sizeof(struct index));
	if (NULL == allocate) {
		fprintf(stderr, "Allocate mem error!\n");
		return -1;
	}
	head = allocate;
	follow = allocate;
	while (!feof(fp)) {
		allocate = (struct index *) malloc(sizeof(struct index));
		if (NULL == allocate) {
			fprintf(stderr, "Allocate mem error!\n");
			return -1;
		}
		memset(allocate->num_str, '\0', NUM);
		fscanf(fp, "%s", text);
		sprintf(allocate->num_str, "%s", text);
		memset(text, '\0', MEM);
		follow->next = allocate;
		follow = allocate;
	}
	allocate->next = NULL;
//	printf("%s\n", follow->num_str);
#if 0
	head = head->next;
	while (NULL != head->next) {
		printf("%s\n", head->num_str);
		head = head->next;
	}
#endif
	fclose(fp);

	_fp = fopen(KEY_FILE, "rt");
	if (NULL == _fp) {
		fprintf(stderr, "fopen file %s error!\n", KEY_FILE);
		return -1;
	}
	_allocate = (struct key *) malloc(sizeof(struct key));
	if (NULL == _allocate) {
		fprintf(stderr, "Allocate mem error!\n");
		return -1;
	}
	_head = _allocate;
	_follow = _allocate;
	memset(_text, '\0', MEM);
	while (!feof(_fp)) {
		fscanf(_fp, "%s", _text);
		if ('A' <= _text[0] && 'Z' >= _text[0]) {
			_follow->next = _allocate;
			_follow = _allocate;
			_allocate = (struct key *) malloc(sizeof(struct key));
			if (NULL == _allocate) {
				fprintf(stderr, "Allocate mem error!\n");
				return -1;
			}
			memset(_allocate->key_str, '\0', NUM);
			_allocate->length = 0;
			sprintf(_allocate->key_str,"%s", _text);
		} else {
			_allocate->num_str[_allocate->length] = (char *) malloc(sizeof(char) * NUM);
			if (NULL == _allocate->num_str[_allocate->length]) {
				fprintf(stderr, "Allocate mem error!\n");
				return -1;
			}
			sprintf(_allocate->num_str[_allocate->length], "%s", _text);
			_allocate->length += 1;
		}
//		printf("999 %s\n", _text);
		memset(_text, '\0', MEM);
	}
	_follow->next = _allocate;
	_follow = _allocate;
	_allocate->next = NULL;
//	printf("%s\n", _allocate->num_str[0]);
#if 0
	_head = _head->next;
	while (NULL != _head) {
		printf("%s\n", _head->key_str);
		for (i = 0; i < _head->length; i++) {
			printf("%s\n", _head->num_str[i]);
		}
		_head = _head->next;
	}
#endif
	fclose(_fp);
	ret = map_keystr(head, _head);
	if (0 > ret) {
		fprintf(stderr, "map_keystr func error!\n");
		return -1;
	}
	free_jobs(head, _head);
	return 0;
}